package cn.szzsi.common.util;



import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.Key;

/**
 * 运算模式CBC。<br>
 * 在CBC模式下使用key,向量iv;<br>
 * 对字符加密时，双方采用的都是UTF-8编码
 */
public class DesUtil {
    // 向量
    //private static final byte[] keyiv = "apmsjfsc".getBytes();

    /**
     * CBC解密
     * @param key 密钥
     * @param data Base64编码的密文
     * @return 明文
     * @throws Exception
     */
    public static byte[] desDecodeCBC(byte[] key, byte[] data,String keyiv) throws Exception {
        Key deskey = null;
        DESKeySpec spec = new DESKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DES");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(keyiv.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }

    /**
     * CBC解密
     * @param key 密钥
     * @param data Base64加密后的密文
     * @return 明文
     * @throws Exception
     */
    public static String desDecodeCBC(String key, String data) throws Exception {
        byte[] _data = Base64.decodeBase64(data);
        byte[] _key = key.getBytes("UTF-8");
        byte[] bOut = desDecodeCBC(_key, _data,key);
        return new String(bOut, "UTF-8");
    }

    /**
     * CBC加密
     * @param key 密钥
     * @param data 明文
     * @return 密文
     * @throws Exception
     */
    public static byte[] desEncodeCBC(byte[] key, byte[] data,String keyiv) throws Exception {
        Key deskey = null;
        DESKeySpec spec = new DESKeySpec(key);
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DES");
        deskey = keyfactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); // 加密方法／运算模式／填充模式
        IvParameterSpec ips = new IvParameterSpec(keyiv.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
        byte[] bOut = cipher.doFinal(data);
        return bOut;
    }

    /**
     * CBC加密
     *
     * @param key 密钥
     * @param data 明文
     * @return Base64加密后的密文
     * @throws Exception
     */
    public static String desEncodeCBC(String key, String data) throws Exception {
        byte[] _data = data.getBytes("UTF-8");
        byte[] _key = key.getBytes("UTF-8");
        byte[] bOut = desEncodeCBC(_key, _data,key);
        return Base64.encodeBase64String(bOut); // Base64加密后的密文
    }

    /**
     * 加密
     * @param key 秘钥
     * @param data 加密数据
     */
    public static String desEncode(String key,String data){
        String info="";
        try {
            info=desEncodeCBC(key,data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return info;
    }


    /**
     * 解密
     * @param key 秘钥
     * @param info 加密字符串
     * @return
     */
    public static String desDecode(String key,String info){
        String str="";
        try {
            str = desDecodeCBC(key,info);// 解密
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }

    public static void main(String[] args) {//测试账号1
        String data="1009"+"&"+new String(Base64.encodeBase64("测试账号1".getBytes()))+"&"+"13900002111"+"&"+1494311087;
        System.out.println("data---------------"+data);
        String str=desEncode("apmsjfsc",data);
        System.out.println("加密后--------------------"+str);
        String str2=desDecode("apmsjfsc",str);
        System.out.println("解密"+str2);

        try {
            String  redirect_uri = URLEncoder.encode(str,"utf-8");
            System.out.println(redirect_uri);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        System.out.println(new String(Base64.encodeBase64("测试账号1".getBytes())));
        System.out.println(new String(Base64.decodeBase64("5rWL6K+V6LSm5Y+3MQ==")));
    }


}
